//
//  HomeViewController.swift
//  A-star
//
//  Created by xukai on 2018/1/8.
//  Copyright © 2018年 xukai. All rights reserved.
//

import UIKit

class HomeViewController: UIViewController ,GridCellDelegate{
    
    
    enum SetCellStyle {
        
        case Default // 默认
        case Start // 起点
        case End // 终点
        case Hinder // 障碍
    }
    
    private var setStyle = HomeViewController.SetCellStyle.Default // 编辑
    private var isEdit = false
    private var isFind = false
    
    private var playView = UIView()
    private var timer : Timer!
    
    private var cellNums = 20
    private var currentNums = 0
    private var cellList = [Array<GridCell>]()
    
    private var openList = NSMutableArray()
    private var closeList = NSMutableArray()
    
    
    private var startCell : GridCell?
    private var endCell : GridCell?
    private var hinderList = [GridCell]()
    

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }

    func setupUI() {
        print(UIScreen.main.bounds)
        self.playView.frame = CGRect(x: 0, y: 44, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)
        self.playView.backgroundColor = UIColor.lightGray
        self.view.addSubview(self.playView)
        makeCell()
        makeLine()

    }
    
    
    func makeLine()  {
        // 画出格子线条
        let n = cellNums
        let wh = UIScreen.main.bounds.width / CGFloat(n)
        for i in 0 ..< n
        {
            self.playView.drawLineWithSpoint(sPoint: CGPoint(x: CGFloat(i) * wh, y: 0), ePoint: CGPoint(x: CGFloat(i) * wh, y: self.playView.frame.height), w: 0.5, color: UIColor.black)
            
            self.playView.drawLineWithSpoint(sPoint: CGPoint(x: 0, y: CGFloat(i) * wh), ePoint: CGPoint(x: self.playView.frame.width, y: CGFloat(i) * wh), w: 0.5, color: UIColor.black)
        }
    }
    
    
    // 设置起点
    @IBAction func setStartCellClick(_ sender: Any) {
        setStyle = .Start
        isEdit = true
        
    
    }
    
    // 设置终点
    @IBAction func setEndCellClick(_ sender: Any) {
        setStyle = .End
        isEdit = true
    }
    
    // 设置障碍
    @IBAction func setHinderCellClick(_ sender: Any) {
        setStyle = .Hinder
        isEdit = true
    }
    
    // 清空
    @IBAction func cleanCellClick(_ sender: Any?) {
        setStyle = .Default
        isEdit = false
        
        for i in 0..<cellNums
        {
            for j in 0..<cellNums
            {
                let cell = cellList[i][j]
                cell.backgroundColor = UIColor.orange
                cell.cellStyle = .Default
            }
        }
        
    }
    
    // 运行
    @IBAction func playClick(_ sender: Any) {
        
//        if(isFind == true)
//        {
//            cleanCellClick(nil)
//            isFind = false
//        }
        
        
        setStyle = .Default
        isEdit = false
        
        if(startCell == nil)
        {
            print("请设置起点")
            return
        }
        if(endCell == nil)
        {
            print("请设置终点")
            return
        }
        findPath(sCell: startCell!, eCell: endCell!)
    }
    
    
    // MARK : GridCellDelegate
    func gridCellClisk(cell : GridCell)
    {
        switch setStyle {
        case .Start:
            
            if cell.cellStyle == .End || cell.cellStyle == .Hinder
            {
                return
            }
            
            let tempCell = startCell
            startCell = cell
            startCell?.backgroundColor = UIColor.red
            startCell?.cellStyle = .Start
            
            tempCell?.backgroundColor = UIColor.orange
            tempCell?.cellStyle = .Default
            
        case .End:
            if cell.cellStyle == .Start || cell.cellStyle == .Hinder
            {
                return
            }
            
            let tempCell = endCell
            endCell = cell
            endCell?.backgroundColor = UIColor.green
            endCell?.cellStyle = .End
            
            tempCell?.backgroundColor = UIColor.orange
            tempCell?.cellStyle = .Default
        case .Hinder:
            
            if cell.cellStyle == .Start || cell.cellStyle == .End || hinderList.contains(cell)
            {
                return
            }
            
            cell.backgroundColor = UIColor.black
            cell.cellStyle = .Hinder
            hinderList.append(cell)
            
        case .Default:
            print("")
        default:
            print("")
        }
        
    }

    
    func makeCell() {
        let wh = UIScreen.main.bounds.width / CGFloat(cellNums)

        for i in 0 ..< cellNums
        {
            var rowList = [GridCell]()
            for j in 0 ..< cellNums
            {
                let cell1 = GridCell(frame: CGRect(x: CGFloat(j) * wh, y: CGFloat(i) * wh, width: wh, height: wh))
                self.playView.addSubview(cell1)
                cell1.p = CGPoint(x: i, y: j)
                cell1.delegate = self 
                rowList.append(cell1)
            }
            cellList.append(rowList)
        }
        
        

    }
    
    
    
    
    
    func findPath(sCell : GridCell, eCell : GridCell)
    {
        openList.add(sCell)
        
        while openList.count != 0
        {
            var curCell = openList[0] as! GridCell
            
            // 获取最小F
            for i in 0..<openList.count
            {
                let tmCell = openList[i] as! GridCell
//                tmCell.backgroundColor = UIColor.green
                if(tmCell.F <= curCell.F)
                {
                    curCell = tmCell
                }
            }
            openList.remove(curCell)
            closeList.add(curCell)
           
            // 找到目标节点
            if curCell == eCell
            {
                print("------------ success ---------")
                
                generatePath(sCell: sCell, eCell: eCell)
                return
            }
            
            // 遍历周围的点
            let neibList = AStarTool.getNeibourhood(p: curCell.p, max: cellNums)
            for i in 0..<neibList.count
            {
                
                let tP = neibList[i]
                let cell = cellList[Int(tP.x)][Int(tP.y)]
                // 如果是墙或者已经在关闭列表中
                if(cell.cellStyle == GridCell.CellStyle.Hinder || closeList.contains(cell))
                {
                    continue
                }
                
                // 计算G值
                let newG = curCell.G + AStarTool.getDistance(p1: sCell.p, p2: cell.p)

                // 如果距离更小，或者原来不在开始列表中
                if newG < cell.G || openList.contains(cell) == false
                {
                    // 更新与开始节点的距离
                    cell.G = newG
                    // 更新与终点的距离
                    cell.H = AStarTool.getDistance(p1: cell.p, p2: eCell.p)

                    // 更新父节点
                    cell.prentCell = curCell
                    
                    // 如果节点不在openList中
                    if(openList.contains(cell) == false)
                    {
                        openList.add(cell)
                    }
                    
                }
                
            }


        }
        
        generatePath(sCell: sCell, eCell: nil)
        
    }
    
    
    func generatePath(sCell : GridCell?, eCell : GridCell?)  {
        var path = Array<GridCell>()
        if(eCell != nil)
        {
            var tmpCell = eCell
            while tmpCell != sCell && tmpCell != nil
            {
                
                tmpCell?.backgroundColor = UIColor.white
                if(tmpCell == eCell)
                {
                    tmpCell?.backgroundColor = UIColor.green
                }
                
                
                path.append(tmpCell!)
                tmpCell = tmpCell?.prentCell
            }
            
            
            isFind = true
        }
        else
        {
            isFind = false
            print("--------- failure --------")
        }
    }


}
